package obecto.component.button
{
	import flash.display.DisplayObject;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	
	import obecto.core.FLUIComponent;
	import obecto.core.IStateClient;
	import obecto.transition.State;
	import obecto.transition.TransitionsManager;

	[Event(name="click", type="flash.events.MouseEvent")]
	[Event(name="rollOver", type="flash.events.MouseEvent")]
	[Event(name="rollOut", type="flash.events.MouseEvent")]
	public class Button extends FLUIComponent implements IStateClient
	{
		//****************************************
		// Model:
		//****************************************
		private var _enabled : Boolean = true;
		[Bindable]
		public function set enabled(value : Boolean) : void 
		{
			_enabled = value;
			if (state != null)
			{
				setState(resolveState(State(state).name));
			}
		}
		public function get enabled() : Boolean
		{
			return _enabled;
		}
		
		protected var _label : String;
		[Bindable]
		public function set label(value : String) : void 
		{
			_label = value;
			if (textField != null)
			{
				textField.htmlText = _label;
			}
		}
		public function get label() : String
		{
			return _label;
		}
		
		private var _selected : Boolean = false;
		public function set selected(value : Boolean) : void 
		{
			if (value != _selected)
			{
				_selected = value;
				setState(resolveState(State(state).name));
			}
		}
		public function get selected() : Boolean 
		{
			return _selected;
		}
		
		public var selectable : Boolean = false;
		public var selectOnClick : Boolean = true;
		
		//****************************************
		// IStateClient implementation:
		//****************************************
		public function set state(value : Object) : void
		{
			if (value is String)
			{
				setState(String(value));
			}
			else if (value is State)
			{
				transitionsManager.state = value;
			}
		}
		public function get state() : Object
		{
			return transitionsManager != null ? transitionsManager.currentState : null;
		}
		
		protected var transitionsManager : TransitionsManager;
		
		//****************************************
		// View:
		//****************************************
		public var textField : TextField;
		public var hit : DisplayObject;
		
		public function Button()
		{
			super();
		}
		
		//****************************************
		// Initialization:
		//****************************************
		override protected function initialize() : void
		{	
			if (label != null && textField != null)
			{
				textField.htmlText = label;
			}
			selected = _selected;
			enabled = _enabled;
			
			if(!hit)
			{
				hit = view;
			}
			
			hit.addEventListener(MouseEvent.ROLL_OVER, handleRollOver);
			hit.addEventListener(MouseEvent.ROLL_OUT, handleRollOut);
			hit.addEventListener(MouseEvent.MOUSE_DOWN, handleMouseDown);
			hit.addEventListener(MouseEvent.MOUSE_UP, handleMouseUp);
			hit.addEventListener(MouseEvent.CLICK, handleMouseClick, true, int.MAX_VALUE);
			hit.addEventListener(MouseEvent.CLICK, handleMouseClick, false, int.MAX_VALUE);
		}
		
		protected function setState(st : String) : void
		{
			if (transitionsManager != null)
			{
				transitionsManager.state = st;
			}
		}
		
		protected function resolveState(state : String) : String
		{
			var result : String;
			var isSelected : Boolean = selectable ? selected : false;
			
			if (enabled)
			{
				switch (state)
				{
					case ButtonStates.OVER:
					case ButtonStates.SELECTED_OVER:
						result = isSelected ? ButtonStates.SELECTED_OVER : ButtonStates.OVER;
					break;
					
					case ButtonStates.DOWN:
					case ButtonStates.SELECTED_DOWN:
						result = isSelected ? ButtonStates.SELECTED_DOWN : ButtonStates.DOWN;
					break;
					
					case ButtonStates.UP:
					case ButtonStates.SELECTED_UP:
						result = isSelected ? ButtonStates.SELECTED_UP : ButtonStates.UP;
					break;
					
					case ButtonStates.DISABLED:
						result = isSelected ? ButtonStates.SELECTED_UP : ButtonStates.UP;
					break;
					
					case "undefined":
						if (hit.hitTestPoint(stage.mouseX, stage.mouseY, true))
						{
							result = isSelected ? ButtonStates.SELECTED_OVER : ButtonStates.OVER;
						}
						else
						{
							result = isSelected ? ButtonStates.SELECTED_UP : ButtonStates.UP;
						}
					break;
				}
			}
			else
			{
				result = ButtonStates.DISABLED;
			}
			
			return result;
		}
		
		//****************************************
		// Handlers:
		//****************************************
		protected function handleRollOver(e : MouseEvent) : void 
		{
			setState(resolveState(ButtonStates.OVER));
			dispatchEvent(new MouseEvent(MouseEvent.ROLL_OVER, true, false, mouseX, mouseY));
		}
		
		protected function handleRollOut(e : MouseEvent) : void 
		{
			setState(resolveState(ButtonStates.UP));
			dispatchEvent(new MouseEvent(MouseEvent.ROLL_OUT, true, false, mouseX, mouseY));
		}
		
		protected function handleMouseDown(e : MouseEvent) : void 
		{
			setState(resolveState(ButtonStates.DOWN));
		}
		
		protected function handleMouseUp(e : MouseEvent) : void 
		{
			if (selectable && selectOnClick)
			{
				selected = !selected;
			}
			setState(resolveState(ButtonStates.OVER));
			dispatchEvent(new MouseEvent(MouseEvent.CLICK));
		}
		
		protected function handleMouseClick(e : MouseEvent) : void 
		{
			// swallow the CLICK event:
			e.stopImmediatePropagation();
		}
		
	}
}